package com.zj.blockchain.controller.advice;

import com.zj.blockchain.controller.entity.Result;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

/**
 * @author zhaojin
 */
@RestControllerAdvice
public class GlobalControllerAdvice implements ResponseBodyAdvice<Object> {

    private static String[] ignores = new String[]{
            //过滤swagger相关的请求的接口，不然swagger会提示base-url被拦截
            "/swagger-resources",
            "/v2/api-docs"
    };

    /**
     * 判断url是否需要拦截
     *
     * @param uri
     * @return
     */
    private boolean ignoring(String uri) {
        for (String string : ignores) {
            if (uri.contains(string)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        if (this.ignoring(serverHttpRequest.getURI().toString())) {
            return body;
        }
        //如果返回的数据是Result、Byte、String类型则不进行封装
        if (body instanceof Result || body instanceof Byte || body instanceof String) {
            return body;
        }
        return this.getWrapperResponse(serverHttpRequest, body);
    }

    /**
     * 返回正常的信息
     *
     * @param request
     * @param data
     * @return
     */
    private Result<Object> getWrapperResponse(ServerHttpRequest request, Object data) {

        return new Result<>(true, "请求成功", data);
    }
}
